<script lang="ts" setup>
import DevicePartCards from "./components/DevicePartCards.vue";
import { distributionDeviceStatusList as defaultDistributionDeviceStatusList } from "./pulping-machines/pulping-machine-parts";
import PartItem from "./components/PartItem.vue";
import { LogLevel } from "./components/types";
import LogItem from "./components/LogItem.vue";
import type { LogItemInfo } from "./types";
import { HttpClient } from "@/utils/http-client";
import { ref } from "vue";
import type { DeviceHostResponse } from "../device-ops/types/device-host-response";
import type { ProductionProcessResponse } from "../device-ops/types/production-process-response";
import type { ProductionWorkshopResponse } from "../device-ops/types/production-workshop-response";
import type { ProductionBaseResponse } from "../device-ops/types/production-base-response";
import { onMounted } from "vue";
import { onUnmounted } from "vue";
import { useRoute } from "vue-router";
import { String } from "@/utils/string";
import type { CharacteristicDictionary } from "./types";
import type { DispatcherMessage } from "./types";
import type { DeviceMaintenanceResponse } from "../device-ops/types/device-maintenance-response";
import { SignalRClient } from "@/utils/signalr-client";
import type { DevicePartResponse } from "../device-ops/types/device-part-response";
import type { PartStatusItem } from "./types";
import PolygonalLines from "./components/PolygonalLines.vue";
import lines from "./pulping-machines/pulping-machine-lines";

const siteName = ref("XXX基地");
const workshorpName = ref("XXX车间");
const processName = ref("XXX工序");
const deviceHostName = ref("XXXXXX系统");
const deviceName = ref("XX#-XXXXXXXX");
const logItemInfoList = ref<LogItemInfo[]>([]);
const isLoading = ref(false);
const baseUrl = import.meta.env.VITE_DEVICE_OPS_SERVICE_BASE_URL;
const httpClient = new HttpClient();
const route = useRoute();
const deviceId = ref("");
const distributionDeviceStatusList = ref(defaultDistributionDeviceStatusList);
const characteristicMapping: CharacteristicDictionary = {};
let signalrClient: SignalRClient | null = null;
const partStatusItemList = ref<PartStatusItem[]>([]);

onUnmounted(async () => {
  await signalrClient?.disconnectAsync();
});

onMounted(async () => {
  isLoading.value = true;
  try {
    const idString: string = route.query.deviceId as string;
    if (!String.isNullOrWhitespace(idString)) {
      deviceId.value = idString;
      initCharacteristicMapping();
      await updateDeviceParts(deviceId.value);
    }
  } finally {
    isLoading.value = false;
  }
});

function initCharacteristicMapping() {
  distributionDeviceStatusList.value.forEach((item) => {
    Object.entries(item.characteristicItems).forEach(([, value]) => {
      characteristicMapping[item.title + "-" + value.label] = value;
    });
  });
}

async function OnDispatcherAsync(arg: DispatcherMessage) {
  const date = new Date();
  addLog(
    `设备特征-${arg.task.deviceName}`,
    `特征点：${arg.task.taskName}\n特征值：${arg.value}\n时间：${date.toLocaleString()}`,
    LogLevel.Normal
  );

  const obj = characteristicMapping[arg.task.taskName];
  obj.value = arg.value;
}

async function getDevicePartsAsync(deviceId: string) {
  const maintenance = await httpClient.getAsync<DeviceMaintenanceResponse>(
    baseUrl + "/device-maintenances/" + deviceId
  );
  deviceName.value = maintenance.deviceName;
  await udpateHeaderInfoAsync(maintenance.deviceHostId);

  if (signalrClient == null) {
    signalrClient = new SignalRClient(deviceHostName.value + "-" + deviceName.value);
  }

  try {
    if (!signalrClient.isConnected()) {
      await signalrClient.connectAsync();
      if (signalrClient.isConnected()) {
        signalrClient.getConnection().on("OnDispatcherAsync", OnDispatcherAsync);
      }
    }
  } catch (err) {
    console.log(err);
  }

  const parts = await httpClient.getAsync<DevicePartResponse[]>(
    baseUrl + "/device-maintenances/" + maintenance.id + "/parts"
  );
  return parts;
}

async function updateDeviceParts(currentDeviceId: string) {
  const parts = await getDevicePartsAsync(currentDeviceId);
  partStatusItemList.value = [];
  parts.forEach((item) => {
    addLog(
      item.devicePartName + "-运行信息",
      `当前寿命：${item.currentLifetime}\n停机寿命：${item.accumulatedDowntime}\n经济寿命：${item.economicLifetimeThreshold}`,
      LogLevel.Normal
    );
    partStatusItemList.value.push({
      partName: item.devicePartName,
      percentage: Math.floor((item.currentLifetime / item.accumulatedDowntime) * 100),
      runingStatus: "lightgreen"
    });
  });
}

async function udpateHeaderInfoAsync(deviceHostId: string) {
  const deviceHost = await httpClient.getAsync<DeviceHostResponse>(
    baseUrl + "/device-hosts/" + deviceHostId
  );
  deviceHostName.value = deviceHost.deviceHostName;

  const process = await httpClient.getAsync<ProductionProcessResponse>(
    baseUrl + "/production-processes/" + deviceHost.productionProcessId
  );
  processName.value = process.processName;

  const workshop = await httpClient.getAsync<ProductionWorkshopResponse>(
    baseUrl + "/production-workshops/" + process.productionWorkshopId
  );
  workshorpName.value = workshop.workshopName;

  const base = await httpClient.getAsync<ProductionBaseResponse>(
    baseUrl + "/production-bases/" + workshop.siteId
  );
  siteName.value = base.siteName;
}

function addLog(title: string, text: string, level: LogLevel) {
  if (logItemInfoList.value.length > 20) {
    logItemInfoList.value.pop();
  }
  logItemInfoList.value.unshift({ logLevel: level, title: title, text: text });
}
</script>

<template>
  <el-scrollbar>
    <div class="main-container">
      <div class="search-container">
        <el-text>基地：{{ siteName }}</el-text>
        <el-text style="margin-left: 32px">车间：{{ workshorpName }}</el-text>
        <el-text style="margin-left: 32px">工序：{{ processName }}</el-text>
        <el-text style="margin-left: 32px">设备主机：{{ deviceHostName }}</el-text>
        <el-text style="margin-left: 32px">设备名称：{{ deviceName }}</el-text>
      </div>
      <div class="content-container">
        <img
          src="@/assets/images/pulping-machine.png"
          style="
            position: absolute;
            left: 50%;
            top: 50%;
            width: 560px;
            transform: translate(-50%, -50%);
            z-index: 0;
          "
          class="cursor-hover"
        />
        <DevicePartCards :items="defaultDistributionDeviceStatusList"></DevicePartCards>
        <el-card class="content-status" shadow="hover">
          <el-scrollbar style="height: calc(937px - 120px)">
            <PartItem
              v-for="(item, index) in partStatusItemList"
              :key="index"
              :part-name="item.partName"
              :percentage="item.percentage"
              :runing-status="item.runingStatus"
            ></PartItem>
          </el-scrollbar>
        </el-card>
        <el-card class="content-right" shadow="hover">
          <el-scrollbar style="height: calc(937px - 120px)">
            <LogItem
              v-for="(item, index) in logItemInfoList"
              :key="index"
              :log-level="item.logLevel"
              :title="item.title"
              :text="item.text"
            ></LogItem>
          </el-scrollbar>
        </el-card>
        <div class="lines-container">
          <PolygonalLines :lines="lines"></PolygonalLines>
        </div>
      </div>
    </div>
  </el-scrollbar>
</template>

<style scoped lang="scss">
.main-container {
  display: flex;
  flex-direction: column;
  background-color: #100b30;
  border-radius: 5px;
  padding: 8px;
  width: 1920px;
  height: 937px;
  margin: 0;
  overflow: hidden;
  position: relative;

  .search-container {
    margin-top: 8px;
    margin-left: 8px;
    color: white;
    font-size: 16px;

    :deep(.el-text) {
      color: white;
      font-size: 16px;
    }
  }
}

.content-container {
  padding: 0px 30px 20px 30px;
  border-radius: 5px;
  width: 100%;
  height: 100%;
  position: relative;
  overflow: hidden;
  .content {
    position: absolute;
    left: 37%;
    z-index: 99;
    top: 46%;
  }
  :deep(.el-card) {
    border-radius: 10px;
    border: 1px;
    background: linear-gradient(90deg, rgb(47 18 115) 0%, #54277da8 100%);
    box-shadow: 0px 0px 5px #6167e4;
    color: #fff;
    &:hover {
      cursor: pointer;
      box-shadow: 0px 0px 10px #ee82ee;
    }
  }
  .content-title {
    position: absolute;
    left: 48.5%;
    top: 10px;
    font-weight: bold;
    font-size: 30px;
    color: #fff;
    transform: translateX(-50%);
  }
  .content-status {
    width: 300px;
    position: absolute;
    left: 15px;
    bottom: 15px;

    .none-content {
      display: flex;
      justify-content: center;
      color: white;
      font-size: 16px;
    }
  }
  .lines-container {
    position: absolute;
    width: 100%;
    height: 100%;
    z-index: 99;
    pointer-events: none;
  }
  .content-right {
    width: 300px;
    position: absolute;
    right: 15px;
    bottom: 15px;

    .none-content {
      display: flex;
      justify-content: center;
      color: white;
      font-size: 16px;
    }

    .right-top {
      font-weight: bold;
    }
    .right-center {
      display: inline;
      color: green;
    }
    .right-foot {
      display: inline;
      color: red;
    }
  }
  .content-main {
    .content-main-title {
      margin-top: 10px;
      .title {
        display: inline-block;
        width: 100px;
      }
      .value {
        display: inline-block;
      }
    }
  }
  .main-img {
    position: absolute;
    left: 50%;
    top: 50%;
    // width: 800px;
    width: 42%;
    // height: 100%;
    transform: translate(-50%, -50%);
  }
}

.d-f {
  display: flex;
}
</style>
